package com.hd.trans.ui.model

import androidx.lifecycle.MutableLiveData
import com.hd.trans.framework.click.XClickUtil
import com.hd.trans.network.ApiServiceManager
import com.hd.trans.network.apiService.ApiException
import com.hd.trans.network.bean.RCFileType
import com.hd.trans.network.bean.RCOcrConvert
import com.hd.trans.network.bean.RCUploadParBean
import com.hd.trans.network.bean.RCUploadPointPar
import com.hd.trans.network.bean.TaskType
import com.hd.trans.network.component.FileTranslateCallback
import com.hd.trans.network.component.FileTranslateManager
import com.hd.trans.share.DownloadArg
import com.hd.trans.utils.FileTranslationUtil
import com.hd.trans.utils.FileUtilsKotlin
import com.hd.trans.utils.LogUtil
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File

class FileTranslateModel: LanguageModel() {
    val mLoadingMsg = MutableLiveData<String>()
    val mErrorMsg = MutableLiveData<String>()
    val isShowLoadingDialog = MutableLiveData<Boolean>()
    private var account: String? = null
    private var usertoken: String? = null

    private val fileTranslateManager by lazy {
        FileTranslateManager().apply {
            setFileTranslateCallback(object : FileTranslateCallback {
                private var transTaskId: String? = null
                override fun startTranslate() {
                    isShowLoadingDialog.value = true
                    setLoadingTips("创建任务")
                }

                override fun onTaskId(taskId: String?) {
                    transTaskId = taskId
                }

                override fun onTaskStatus(
                    status: String?,
                    estimatedTime: Long,
                    pendingCount: Int,
                    progress: Int,
                ) {
                    if("pending" == status) {
                        /*if(estimatedTime > 0){
                            setLoadingTips("预估:${AudioTimeFormatUtil.formatMin(estimatedTime)}")
                        }else */
                        if (pendingCount >= 0) {
                            //setLoadingTips("排队中：$pendingCount")
                            setLoadingTips("等待中...")
                        }
                    }else if ("running" == status || "success" == status) {
                        setLoadingTips("翻译 ${progress}%")
                    }else if ("downloading" == status) {
                        setLoadingTips("下载中...")
                    }
                }

                override fun onTranslateCompleted(
                    originalContent: String?,
                    transContent: String?,
                    fromLangCode: String?,
                    toLangCode: String?,
                    status: Boolean,
                ) {
                }

                override fun onTranslateFailed(code: Int, msg: String?) {
                    isShowLoadingDialog.value = false
                }

                override fun onDownloadStart(downloadArg: DownloadArg?) {
                    //setLoadingTips("下载中")
                }
                override fun onDownloadProgress(downloadArg: DownloadArg?, progress: Int) {
                    /*val percentage = DecimalFormat("00").format(progress)
                    setLoadingTips("下载中:$percentage%")*/
                }
                override fun onDownloadError(downloadArg: DownloadArg?) {
                    isShowLoadingDialog.value = false
                }
                override fun onDownloadComplete(downloadArg: DownloadArg?) {
                    if(transTaskId != downloadArg?.taskId){
                        return
                    }
                    downloadArg?.let { arg ->
                        if (XClickUtil.isInterval(1000)) {
                            return
                        }
                        isShowLoadingDialog.value = false
                        var result = true
                        val it: Iterator<String> = arg.targetFileAbsPaths.iterator()
                        while (it.hasNext()) {
                            val filePath: String = it.next()
                            if(!File(filePath).exists()){
                                result = false
                            }
                        }
                        if(!result){
                            //下载文件缺失
                            mErrorMsg.value = "下载文件缺失"
                            return
                        }
                        val translateFilePath = downloadArg.targetFileAbsPaths[0]
                        val originalText = downloadArg.targetFileAbsPaths[1]
                        val translateText = downloadArg.targetFileAbsPaths[2]
                        val inpaintedFilePath = downloadArg.targetFileAbsPaths[3]
                        val metaFilePath = downloadArg.targetFileAbsPaths[4]
                        //打印
                        LogUtil.d("FileTranslateModel", "translateFilePath: $translateFilePath")
                        LogUtil.d("FileTranslateModel", "originalText: $originalText")
                        LogUtil.d("FileTranslateModel", "translateText: $translateText")
                        LogUtil.d("FileTranslateModel", "inpaintedFilePath: $inpaintedFilePath")
                        LogUtil.d("FileTranslateModel", "metaFilePath: $metaFilePath")
                    }
                }
            })
        }
    }

    private fun setLoadingTips(s: String) {
        mLoadingMsg.value = s
        LogUtil.d("FileTranslateModel", s)
    }

    /**文件翻译*/
    fun executeTrans(filePath: String){
        if (getLanguageFromCode().isEmpty() || getLanguageToCode().isEmpty()) {
            mErrorMsg.value = "请选择语言"
            return
        }
        if(!FileTranslationUtil.isSupportedFormat(filePath)){
            mErrorMsg.value = "不支持的文件格式"
            return
        }
        fileTranslateManager.fileTranslate(
            getLanguageFromCode(),
            getLanguageToCode(),
            filePath,"auto",1,0, "")
    }

    //执行文档翻译
    fun executeTranslateDocument(filePath: String, account: String? = null, usertoken: String? = null){
        this.account = account
        this.usertoken = usertoken
        val file = File(filePath)
        if(!file.exists()){
            mErrorMsg.value = "文件不存在"
            return
        }
        MainScope().launch {
            try {
                createTranslateTask(filePath)
            }catch (e: Throwable){
                e.printStackTrace()
            }
        }

    }

    private suspend fun createTranslateTask(filePath: String) {
        val file = File(filePath)
        val fileName = FileUtilsKotlin.getUniqueName(file.name)
        val uploadBean = RCUploadParBean(filename = fileName)
        uploadBean.tasktype = TaskType.translate
        uploadBean.fanyi_from = getLanguageFromCode()
        uploadBean.fanyi_to = getLanguageToCode()
        uploadBean.parainfo = "maxlimit:char0page0"//默认返回所有页
        uploadBean.usertoken = usertoken
        /**
         * pdf转输出word便于用户编辑，其他输入什么类型就输入什么类型
         */
        if (FileUtilsKotlin.isPdfFile(fileName)) {
            uploadBean.outputfileextension = RCFileType.DOCX.suffix
        } else {
            uploadBean.outputfileextension = FileUtilsKotlin.getExtension(fileName)
        }
        val uploadPointPar = ApiServiceManager.apiV4Service.uploadpar(uploadBean.toRequestBody())
        val list = FileTranslationUtil.splitFile(file)
        updateFileInfo(uploadPointPar, list)
    }

    private suspend fun updateFileInfo(uploadPointPar: RCUploadPointPar, list: ArrayList<File>){
        val (taskTag, taskToken, timestamp) = uploadPointPar
        list.forEachIndexed { index, file ->
            val body = file.asRequestBody("application/octet-stream".toMediaTypeOrNull())
            ApiServiceManager.apiV4Service.uploadfile(
                taskTag,
                timestamp,
                taskToken,
                index,
                list.size,
                0,
                body)
        }

        //轮询间隔
        val uploadProgress = 10
        val specialValue = 70
        var intervalTime: Long
        var taskState: RCOcrConvert? = null
        var queryTimes = 1

        do {
            intervalTime = when (queryTimes) {
                in 1..4 -> {
                    2000
                }
                in 5..10 -> {
                    3000
                }
                else -> {
                    5000
                }
            }
            try {
                taskState = ApiServiceManager.apiV4Service.queryTaskState(taskTag, 0, account, usertoken)
            } catch (e: Throwable) {
                e.printStackTrace()
            }
            if (taskState?.isResponseSuccess == true) {
                break
            }
            taskState?.code?.let {
                if (it != 20000) {
                    throw ApiException(it, taskState.requestUrl)
                }
            }
            val tempProgress = if(queryTimes > specialValue){
                specialValue + ((queryTimes - specialValue) / 5)
            }else{
                queryTimes
            }
            val temProcess = if(uploadProgress + tempProgress > 97) 97 else uploadProgress + tempProgress
            //block?.invoke(temProcess)
            queryTimes++
            delay(intervalTime)
        }while (taskState?.isResponseSuccess != true)

        val download = ApiServiceManager.apiV4Service.downloadFile(taskTag, account, usertoken, 2,0)
        val downloadUrl = download.downurl
        handlerDownload(downloadUrl)
    }

    //下载文件
    private suspend fun handlerDownload(downloadUrl: String?, fileName: String = ""): String {
        if (downloadUrl.isNullOrEmpty()) {
            return ""
        }

        //https://ae-1251441578.cos.ap-shanghai.myqcloud.com/ae-1251441578/3ba62880c5bc44831b313a63e1dbbc28/result/d70519901edfea6231785dea3af1eb79.jpg
        val array = downloadUrl.split("?")
        if (array.isEmpty()) {
            return ""
        }
        val body = ApiServiceManager.universalService.download(downloadUrl)
        val downloadFile = FileUtilsKotlin.writeResponseBodyToDisk(body, array[0], fileName)

        if (!downloadFile.exists()) {
            throw ApiException(-1, "下载文件失败")
        }
        LogUtil.d("FileTranslateModel", "handlerDownload: ${downloadFile.absolutePath}")
        return downloadFile.absolutePath
    }
}